#!/usr/bin/perl -w # for syntax highlighting

use gri_conversions;
use gri_secmgr qw(get_user_name);
use gri_mime;

# Portal, report and report number arguments passwd
{
sub _process_file($$$);
my %hash=();

sub _process_file($$$) {
my $portal2=$_[0];
my $report2=$_[1];
my $filename=$_[2];

	my $fd;
	if(!open($fd,$filename)) {
		print STDERR "_process_file: Unable to open '$filename' - ignored.\n";
		return;
	}
	my $url_prefix=$::GRI_FRONTEND->get_url_prefix();
	my ($rep_dir,$err3)=$::GRI_FRONTEND->get_report_directory($report2);
	my ($rep_attr,$err4)=$::GRI_FRONTEND->get_report_attributes($report2);
	my ($tmp_content,$err)=$::GRI_FRONTEND->get_tmp_content_dir();
	my ($tmp_urlref,$err2)=$::GRI_FRONTEND->get_tmp_urlref();
	my $l=join("",<$fd>); close($fd);
	my $newstr="";
	while(1) {
		my $pp;
		($pp)=($l =~ /<img\s+.*?src="(.+?)"/i);
		last if !defined($pp);
		$pp=basename($pp);
		my ($checksum,$err)=$::GRI_FRONTEND->get_file_checksum($portal2,$report2,"$rep_dir/$pp");
		if(!defined($checksum)) {
			last;
		}
		my $x;
		($x)=($pp =~ /\.([a-z]+)$/);
		my $newname=$checksum;
		$newname.=".$x" if defined($x);
		$hash{$pp}=$newname;
		if(! -f "$tmp_content/$newname") {
			print STDERR "_process_file: Attempting to get file...\n";
			my ($content,$err)=$::GRI_FRONTEND->get_file($portal2,$report2,"$rep_dir/$pp");
			if(defined($err)) {
				print STDERR "_process_file: Error getting file: $err\n";
				last;
			}
			open($fd3,">$tmp_content/$newname") or last;
			if(!print $fd3 $$content) {
				close($fd3); unlink("$tmp_content/$newname");
				last;
			}
			close($fd3);
			print STDERR "_process_file: File retrieved!\n";
		}
		#########################################################################
		# The file now exists locally, so replace the reference with the	#
		# local file.								#
		#########################################################################
		my $hh="$url_prefix/$tmp_urlref/$newname";
		$l =~ s/(<img\s+.*?src=)\"(.+?)\"/$1\"$hh\"/i;
		$l =~ /(<img\s+.*?src=)\"(.+?)\"/i;
		my $e=$+[0];
		$newstr.=substr($l,0,$e);
		$l=substr($l,$e);
	}
	$l="$newstr$l";
	$newstr="";
	# Scan the html looking for frame URL's to change if we can
	while(1) {
		my $pp;
		($pp)=($l =~ /<frame\s+.*?src="(.+?)"/i);
		last if !defined($pp);
		$pp=basename($pp);
		my ($checksum,$err)=$::GRI_FRONTEND->get_file_checksum($portal2,$report2,"$rep_dir/$pp");
		if(!defined($checksum)) {
			last;
		}
		my $x;
		($x)=($pp =~ /\.([a-z]+)$/);
		my $newname=$checksum;
		$newname.=".$x" if defined($x);
		$hash{$pp}=$newname;
		if(! -f "$tmp_content/$newname") {
			print STDERR "_process_file: Attempting to get file...\n";
			my ($content,$err)=$::GRI_FRONTEND->get_file($portal2,$report2,"$rep_dir/$pp");
			if(defined($err)) {
				print STDERR "_process_file: Error getting file: $err\n";
				last;
			}
			open($fd3,">$tmp_content/$newname") or last;
			if(!print $fd3 $$content) {
				close($fd3); unlink("$tmp_content/$newname");
				last;
			}
			close($fd3);
			print STDERR "_process_file: File retrieved!\n";
			# Process the file!
			_process_file($portal2,$report2,"$tmp_content/$newname");
		}
		#########################################################################
		# The file now exists locally, so replace the reference with the	#
		# local file.								#
		#########################################################################
		my $hh="$url_prefix/$tmp_urlref/$newname";
		$l =~ s/(<frame\s+.*?src=)\"(.+?)\"/$1\"$hh\"/i;
		$l =~ /(<frame\s+.*?src=)\"(.+?)\"/i;
		my $e=$+[0];
		$newstr.=substr($l,0,$e);
		$l=substr($l,$e);
	}
	# Scan the html looking for link URL's to change if we can
	while(1) {
		my $pp;
		($pp)=($l =~ /<a\s+.*?href="(.+?)"/i);
		last if !defined($pp);
		$pp=basename($pp);
		# If the name contains a # component strip it off for 
		# testing the hash contents.
		my $target="";
		($target)=($pp =~ /(#.*)$/);
		if($target) {
			$pp =~ s/#.*//;
		}
		if(exists($hash{$pp})) {
			my $hh="$url_prefix/$tmp_urlref/$hash{$pp}$target";
			$l =~ s/(<a\s+.*?href=)"(.+?)"/$1\"$hh\"/i;
			$l =~ /(<a\s+.*?src=)"(.+?)"/i;
			my $e=$+[0];
			$newstr.=substr($l,0,$e);
			$l=substr($l,$e);
		} else {
			$l =~ /(<a\s+.*?src=)"(.+?)"/i;
			my $e=$+[0];
			$newstr.=substr($l,0,$e);
			$l=substr($l,$e);
		}
	}
	$l="$newstr$l";
	open($fd,">$filename");
	print $fd $l;
	close($fd);
}

sub mm_portal_file_view($$$$$;$) {
my $portal=$_[0];
my $report=$_[1];
my $repnum=$_[2];
my $repmtime=$_[3];
my $convert=$_[4];
my $as_email_body=$_[5];

	my $mine_info;
	my $mime_file=$::GRI_FRONTEND->get_variable("MIME_FILE");
	if(defined($mime_file)) {
		$mime_info=new gri_mime($mime_file);
	}
	# Abort with error if unable to load mime info
	if(!defined($mime_info)) {
		my $error="Failed to load file containg MIME information.";
		my $error2="Please contact the site administrator if this error continues to occur.";
		my $l=$link="$urlprefix$::ENV{SCRIPT_NAME}/show_error?error=" . string_to_hex($error) . ",error2=" . string_to_hex($error2);
		redirect_header(path => $link);
		exit(0);
	}
	$as_email_body=0 if !defined($as_email_body);
	my $portal2=hex_to_string($portal);
	my $css;
	my $username=get_user_name();
	if(!defined($css)) {
		if(defined($username) && $username ne "public") {
			my $users_dir=$::GRI_FRONTEND->get_global_directory("users");
			if(-f "$users_dir/$username-prefs.xml") {
				my $xx=new gri_userprefs("$users_dir/$username-prefs.xml");
				if($xx) {
					my ($desc,$val)=$xx->get_pref_value("gri_stylesheet");
					if(defined($val)) {
						$css="/stylesheet-$val.css";
					}
				}
			}
		}
	}
	if(!defined($css)) {
		$css=$::ENV{CSS} if exists($::ENV{CSS});
		$css=$::ENV{GRI_STYLE_SHEET} if exists($::ENV{GRI_STYLE_SHEET});
		$css="/StyleGuide.css" if !defined($css);
	}
	# Is this an actual portal - if not report an error...
	# Is this an actual portal - if not report an error...
	$portal2=hex_to_string($portal);
	if(! $::GRI_FRONTEND->does_portal_exist($portal2)) {
		my $error="The portal '$portal2' does not exist.";
		my $error2="This typically occurs if a portal has been removed or the URL has been corrupted.";
		html_error({title=>"System Error",error=>$error,error2=>$error2,link=>undef});
		exit(0);
	}
	
	# Check to see if user allowed and abort if not...
	if(! $::GRI_FRONTEND->is_user_allowed($portal2,$username)) {
		my $n2=string_to_hex($username);
		my $l;
		if($username eq 'test' || $username eq 'nbkkb5h') {
			$l=link_to_str("stdlink","New Request Access","form_portal_access_request","portal=$portal,user=$n2");
		} else {
			$l=link_to_str("stdlink","Request Access","portal_access","portal=$portal,user=$n2");
		}
		my $error="You currently have not been granted access to view reports from the portal '$portal2'. Please click the link below to request access.";
		html_error({title=>"Access Denied - Request Access?",
			error=>$error,error2=>undef,
			"link"=>$l});
		exit(0);
	}
	print STDERR "OK: User '$username' is allowed access to portal '$portal2'.\n";

	load_macro("mm_show_toplevel_crumb");
	load_macro("mm_show_portal_crumb");
	load_macro("mm_show_report_crumb");

	my $report2=hex_to_string($report);
	my ($type,$err2)=$::GRI_FRONTEND->get_report_type($report2);
	my ($_attributes,$err3)=$::GRI_FRONTEND->get_report_attributes($report2);

	#################################################################
	# If we do not have a directly viewable type output the mime	#
	# type information.						#
	#################################################################
	my ($header);
	my $disposition="";
	if($_attributes =~ /force_save/) {
		$disposition="Content-disposition: attachment; ";
	}
	my $repnum2=hex_to_string($repnum);
	my $repmtime2=hex_to_string($repmtime);
	my ($lref,$err,$rname);
	if($repmtime eq "?repmtime - not defined?") {
		($lref,$err,$rname)=$::GRI_FRONTEND->get_report_contents($portal2,$report2,$repnum2);
	} else {
		($lref,$err,$rname)=$::GRI_FRONTEND->get_report_contents_by_mtime($portal2,$report2,$repmtime2);
	}
	if(!defined($rname)) {
		$rname="download";
		$rname.=".$type" if defined($type);
	}
	if(!defined($lref)) {
		print STDERR "Error: mm_portal_file_view :: get_report_contents failed returned $err\n";
		return "ERROR mm_portal_file_view :: $err\n";
	}
	if(defined($convert) && $convert eq "1") {
		my @rinfo=$::GRI_FRONTEND->get_portal_report_details($portal2,$report2);
		my $tmpdir=$::GRI_FRONTEND->get_tmp_content_dir();
		my $gri_conv=new gri_conversions(tmpdir=>$tmpdir);
		my $is_convertable=$gri_conv->can_convert($rinfo[4],$rinfo[6]);
		if($is_convertable==0) {
			return "ERROR mm_portal_file_view :: Unable to convert type '$rinfo[4]' to '$rinfo[6]'.";
		}
		my ($rc,$info)=$gri_conv->do_convert($rinfo[4],$rinfo[6],[$$lref],$rinfo[7]);
		if($rc==1) {
			my $nt=$rinfo[6];
			$rname =~ s/\.$type$/\.$nt/g;
			$type=$rinfo[6];
		} else {
			return "ERROR mm_portal_file_view :: $info";
		}
		$lref=\$info;
	}
	my $dealt=0;
	if(defined($type)) {
		if($type eq "text" && $as_email_body) {
			return $$lref;
		}
		my @I;
		if($type eq "text") {
			@I=$mime_info->get_type_info("html");
		} else {
			@I=$mime_info->get_type_info($type);
		}
		# print STDERR "type=$type\n";
		# print STDERR join("|",@I),"\n";
		if(defined($I[0])) {
			$dealt=1;
			$header="Content-Type: $I[1]\n";
			if(uc($I[3]) eq "ATTACH") {
				$header.="Content-disposition: attachment; filename=\"$rname\"\n\n";
			} else {	
				$header.="\n\n<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"$css\"/>\n<meta http-equiv=\"pragma\" content=\"NO_CACHE\"/></head>\n";
				$header.="\n";
			}
		}
	}
	if(! $dealt) {
		$header="Content-Type: text/html\n\n<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"$css\"/>\n<meta http-equiv=\"pragma\" content=\"NO_CACHE\"/></head>\n";
	}
	my ($rep_dir,$err4)=$::GRI_FRONTEND->get_report_directory($report2);
	if(defined($type) && $type eq "text") {
		# If the type is not 'html' we have to cook it slightly...
		my $new_data="";
		my @L=split(/\n/,$$lref);
		$new_data="<table class=gri_container_maxsize>\n";
		my $row=0;
		for my $cline (@L) {
			my $id="gri_odd";
			$id="gri_even" if $row%2==0;
			my $d=$cline; $d =~ s/ /&nbsp;/g;
			$new_data.="<tr id=$id width=100%><td class=gri_cell style=\"font-family:courier; font-size: 80%\">$d</td></tr>\n";
			$row++;
		}
		$new_data.="</table>";
		if($as_email_body) {
			return "<html>\n<body>\n$new_data\n</body></html>";
		}
		my $str="<br><table width=100% cols=1><tr><td align=right>" . mm_show_toplevel_crumb() . " :: " . mm_show_portal_crumb($portal) . " :: " . mm_show_report_crumb($portal,$report) . "</td></tr></table>";
		return "$header$new_data$str";
	}
	if(defined($type) && $type ne "html") {
		if(defined($as_email_body)) {
			if($as_email_body==2) {
				return $$lref;
			} else {
				return "$header$$lref";
			}
		} else {
			return "$header$$lref";
		}
	}
	# HTML requires us to look for patterns like the following:
	# <img ...>"
	my $tmp_content;
	($tmp_content,$err)=$::GRI_FRONTEND->get_tmp_content_dir();
	if(defined($type) && $type eq "html") {
		my ($tmp_urlref,$err2)=$::GRI_FRONTEND->get_tmp_urlref();
		my $l=$$lref;
		my $newstr="";
		while(1) {
			my $pp;
			($pp)=($l =~ /<img\s+.*?src="(.+?)"/i);
			last if !defined($pp);
			$pp=basename($pp);
			my ($checksum,$err)=$::GRI_FRONTEND->get_file_checksum($portal2,$report2,"$rep_dir/$pp");
			if(!defined($checksum)) {
				last;
			}
			my $x;
			($x)=($pp =~ /\.([a-z]+)$/);
			my $newname=$checksum;
			$newname.=".$x" if defined($x);
			$hash{$pp}=$newname;
			if(! -f "$tmp_content/$newname") {
				my ($content,$err)=$::GRI_FRONTEND->get_file($portal2,$report2,"$rep_dir/$pp");
				if(defined($err)) {
					print STDERR "Error getting file: $err\n";
					last;
				}
				open($fd3,">$tmp_content/$newname") or last;
				if(!print $fd3 $$content) {
					close($fd3); unlink("$tmp_content/$newname");
					last;
				}
				close($fd3);
			}
			#########################################################################
			# The file now exists locally, so replace the reference with the	#
			# local file.								#
			#########################################################################
			my $hh="$url_prefix/$tmp_urlref/$newname";
			$l =~ s/(<img\s+.*?src=)\"(.+?)\"/$1\"$hh\"/i;
			$l =~ /(<img\s+.*?src=)\"(.+?)\"/i;
			my $e=$+[0];
			$newstr.=substr($l,0,$e);
			$l=substr($l,$e);
		}
		$l="$newstr$l";
		$newstr="";
		# Scan the html looking for frame URL's to change if we can
		while(1) {
			my $pp;
			($pp)=($l =~ /<frame\s+.*?src="(.+?)"/i);
			last if !defined($pp);
			$pp=basename($pp);
			my ($checksum,$err)=$::GRI_FRONTEND->get_file_checksum($portal2,$report2,"$rep_dir/$pp");
			if(!defined($checksum)) {
				last;
			}
			my $x;
			($x)=($pp =~ /\.([a-z]+)$/);
			my $newname=$checksum;
			$newname.=".$x" if defined($x);
			$hash{$pp}=$newname;
			if(! -f "$tmp_content/$newname") {
				my ($content,$err)=$::GRI_FRONTEND->get_file($portal2,$report2,"$rep_dir/$pp");
				if(defined($err)) {
					print STDERR "Error getting file: $err\n";
					last;
				}
				open($fd3,">$tmp_content/$newname") or last;
				if(!print $fd3 $$content) {
					close($fd3); unlink("$tmp_content/$newname");
					last;
				}
				close($fd3);
				# Process the file!
				_process_file($portal2,$report2,"$tmp_content/$newname");
			}
			#########################################################################
			# The file now exists locally, so replace the reference with the	#
			# local file.								#
			#########################################################################
			my $hh="$url_prefix/$tmp_urlref/$newname";
			$l =~ s/(<frame\s+.*?src=)\"(.+?)\"/$1\"$hh\"/i;
			$l =~ /(<frame\s+.*?src=)\"(.+?)\"/i;
			my $e=$+[0];
			$newstr.=substr($l,0,$e);
			$l=substr($l,$e);
		}
		# Scan the html looking for link URL's to change if we can
		while(1) {
			my $pp;
			($pp)=($l =~ /<a\s+.*?href=["]{0,1}(.+?)["]{0,1}/i);
			last if !defined($pp);
			$pp=basename($pp);
			# If the name contains a # component strip it off for 
			# testing the hash contents.
			my $target="";
			($target)=($pp =~ /(#.*)$/);
			if($target) {
				$pp =~ s/#.*//;
			}
			if(exists($hash{$pp})) {
				my $hh="$url_prefix/$tmp_urlref/$hash{$pp}$target";
				$l =~ s/(<a\s+.*?href=)["]{0,1}(.+?)["]{0,1}/$1\"$hh\"/i;
				$l =~ /(<a\s+.*?src=)["]{0,1}(.+?)["]{0,1}/i;
				my $e=$+[0];
				$newstr.=substr($l,0,$e);
				$l=substr($l,$e);
			} else {
				$l =~ /(<a\s+.*?src=)["]{0,1}(.+?)["]{0,1}/i;
				my $e=$+[0];
				$newstr.=substr($l,0,$e);
				$l=substr($l,$e);
			}
		}
		$l="$newstr$l";
		$lref=\$l;
	}
	# He we get here we need another pass at the files that have passed
	for my $cfile (keys(%hash)) {
		print STDERR "Processing $cfile [$hash{$cfile}] again...\n";
		_process_file($portal2,$report2,"$tmp_content/$hash{$cfile}");
	}
	# Clear down the hash otherwise we will keep doing the processing for
	# other files that have been viewed.
	%hash=();
	if($as_email_body) {
		my $x=$$lref;
		if($x =~ /(<frame\s+.*?src=)\"(.+?)\"/i) {
			return "<html>$$lref</html>";
		}
		return "<html>\n<body>\n$$lref\n</body></html>";
	}
	my $str="<br><table width=100% cols=1><tr><td align=right>" . mm_show_toplevel_crumb() . " :: " . mm_show_portal_crumb($portal) . " :: " . mm_show_report_crumb($portal,$report) . "</td></tr></table>";
	return "$header$$lref$str";
}

}

